home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 June
/
EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso
/
earcd
/
fonts
/
mvpsf.lha
/
MvPSF1_4
/
MvPSF.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-10
|
25KB
|
853 lines
/*
lc -Lcdv -O -ma -rr -ignu:os-include MvPSF
apf -v gcc -g MvPSF.c -o MvPSF_pure -noixemul -lauto
gcc020 -o MvPSF_gcc -noixemul -m68030 MvPSF.c -lauto -g -v
gcc020 -DAPURIFY -g MvPSF.c -o MvPSF.s -m68030 -noixemul -lauto -S
Apurify -tb MvPSF.s -o MvPSFPure.s
gcc020 -g MvPSFPure.s -o MvPSF_pure -m68030 -noixemul -lauto -lAPur
*/
#define __MA_VERSION__ "$Revision: 1.4 $ $Date: 1996/04/10 21:30:16 $"
static char MvPSF_RCS_Main[] = "$Id: MvPSF.c,v 1.4 1996/04/10 21:30:16 Christophe_Labouisse Exp $";
/* === Section : Includes === */
#include <string.h>
#include <ctype.h>
#include <dos/dos.h>
#include <dos/rdargs.h>
#include <proto/dos.h>
#include <exec/exec.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <proto/exec.h>
#include <clib/alib_protos.h>
#include <utility/tagitem.h>
#ifdef __GNUC__
#include <inline/exec.h>
#include <inline/dos.h>
#include <inline/alib.h>
#else
#include <pragmas/exec.h>
#include <pragmas/dos.h>
#endif
/* === Section : Types === */
typedef enum {TYF_ERR = -1,TYF_NON = 0,TYF_AFM,TYF_PFA,TYF_PFB} TYPE_FICHIER;
typedef struct
{
struct MinNode UF_Node;
int PosDebut; /* début de la partie textuelle */
char fontname[32]; /* chaîne de reconnaissance de FontName */
char finhead[32]; /* chaîne indiquant la fin de l'en-tête */
char type[16]; /* Extension du fichier */
char nom[108]; /* Nom du fichier */
BPTR repertoire; /* Un "Lock" vers le répertoire où se trouve le fichier */
} Un_Fichier;
typedef struct
{
char **fichiers;
LONG verbose,all,stat;
} MvPSF_Args;
typedef struct
{
BOOL verbose,all,stat;
LONG nb_fic_lus,nb_dir_lues;
LONG nb_AFM;
LONG nb_PFB;
LONG nb_PFA;
LONG nb_fic_mv;
APTR mpool;
struct MinList ma_liste;
char *nom_prog;
} MvPSF_Glo;
/* === Section : Consts & Defines === */
/* Fichiers AFM */
const char AFMHeader[] = "StartFontMetrics";
#define AFMHeadlong ((unsigned long)strlen(AFMHeader))
const int PosAFM = 0;
const char AFMFNStr[] = "FontName";
const char AFMFHStr[] = "StartCharMetrics";
/* Fichiers PFB */
const char PFBHeader[] = "\x80\x01";
#define PFBHeadlong ((unsigned long)strlen(PFBHeader))
const int PosPFB = 6;
const char PFBFNStr[] = "/FontName";
const char PFBFHStr[] = "eexec";
/* ------ Fichiers PFA --- */
const char PFA1Header[] = "%!PS-AdobeFont";
#define PFA1Headlong ((unsigned long)strlen(PFA1Header))
const char PFA2Header[] = "%!FontType";
#define PFA2Headlong ((unsigned long)strlen(PFA2Header))
const int PosPFA = 0;
const char PFAFNStr[] = "/FontName";
const char PFAFHStr[] = "eexec";
/* ------ Memory Pool --- */
const int NB_POOL=64;
const int NB_PUDDLE=20;
/* ------ Divers --- */
#ifdef __GNUC__
const int LONG_BUFFER = 64; /* Le nombre d'octets lus au début de chaque fichier */
const int LONGUEUR_NOM = 31; /* La longueur max du nom du programme */
#else
#define LONG_BUFFER 64
#define LONGUEUR_NOM 31
#endif
char Template[] = "FILE/M/A,VERBOSE/S,ALL/S,STAT/S";
/* === Section : Prototypes === */
void traiter_fichier(MvPSF_Glo *contexte,Un_Fichier *fic);
BOOL lecture_repertoire(MvPSF_Glo *contexte,struct FileInfoBlock *info,BPTR rep);
BOOL ajoute_fichier(MvPSF_Glo *contexte,char *nom,Un_Fichier *fic);
TYPE_FICHIER type_fichier(MvPSF_Glo *contexte,BPTR fic);
BOOL recup_mot(MvPSF_Glo *contexte,BPTR fh,char *chaine,int longueur);
/* ------------------------------ main ------------------------------
Le programme principal.
*/
int main(void)
{
struct FileInfoBlock *info;
char mon_nom[32];
MvPSF_Args arguments;
MvPSF_Glo *contexte;
struct RDArgs *RDArgs;
if (!GetProgramName(mon_nom,LONGUEUR_NOM))
{
strcpy(mon_nom,"MvPSF");
}
Printf("\n\033[1m%s\033[m ©1996 Christophe Labouisse %s\n\n",mon_nom,__MA_VERSION__);
arguments.verbose = FALSE;
arguments.all = FALSE;
arguments.stat = FALSE;
RDArgs = ReadArgs(Template,(LONG *)&arguments,NULL);
if (RDArgs)
{
struct AnchorPath *AnchorPath;
AnchorPath = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath),MEMF_PUBLIC|MEMF_CLEAR);
if (AnchorPath)
{
AnchorPath->ap_BreakBits=SIGBREAKF_CTRL_C;
AnchorPath->ap_Strlen=0;
info = AllocDosObjectTags(DOS_FIB,TAG_DONE,NULL);
if (info)
{
contexte = (MvPSF_Glo *)AllocVec(sizeof(MvPSF_Glo),MEMF_CLEAR);
if (contexte)
{
char **les_fichiers;
BPTR ancien_rep;
contexte->all = arguments.all;
contexte->verbose = arguments.verbose;
contexte->stat = arguments.stat;
contexte->nom_prog = mon_nom;
/* Allocation de la 'memory pool' pour la suite */
contexte->mpool = CreatePool(MEMF_CLEAR,sizeof(Un_Fichier)*NB_POOL,sizeof(Un_Fichier)*NB_PUDDLE);
if (contexte->mpool)
{
struct MinNode *node;
les_fichiers = arguments.fichiers;
while (*les_fichiers)
{
LONG RetVal;
NewList((struct List *)&contexte->ma_liste);
if (contexte->verbose)
{
Printf("Processing argument « \033[1m%s\033[m »\n",*les_fichiers);
}
for (RetVal = MatchFirst(*les_fichiers,AnchorPath) ; RetVal == 0 ; RetVal = MatchNext(AnchorPath))
{
BPTR rep_courant;
rep_courant = AnchorPath->ap_Current->an_Lock;
if (AnchorPath->ap_Info.fib_DirEntryType > 0)
{
/* C'est un répertoire */
if (contexte->all)
{
if (!(AnchorPath->ap_Flags & APF_DIDDIR))
{
contexte->nb_dir_lues++;
AnchorPath->ap_Flags |= APF_DODIR;
if (contexte->verbose)
{
Printf("Entering directory \033[1m%s\033[m\n",AnchorPath->ap_Info.fib_FileName);
}
}
else if (contexte->verbose)
{
Printf("Exiting directory \033[1m%s\033[m\n",AnchorPath->ap_Info.fib_FileName);
}
AnchorPath->ap_Flags &= ~APF_DIDDIR;
}
else
{
BOOL rv_lr = FALSE;
BPTR arg_courant;
/* On modifie AnchorPath pour qu'il ne rentre pas dans le répertoire */
AnchorPath->ap_Flags |= APF_DIDDIR;
AnchorPath->ap_Flags &= ~APF_DODIR;
ancien_rep = CurrentDir(rep_courant);
arg_courant = Lock(AnchorPath->ap_Info.fib_FileName,ACCESS_READ);
if (arg_courant)
{
CurrentDir(arg_courant);
if (Examine(arg_courant,info))
{
contexte->nb_dir_lues++;
rv_lr = lecture_repertoire(contexte,info,arg_courant);
}
else
{
Printf("%s : Can't examine %s - ",mon_nom,AnchorPath->ap_Current->an_Info.fib_FileName);
PrintFault(IoErr(),NULL);
}
UnLock(arg_courant);
}
else
{
Printf("%s : Can't lock %s - ",mon_nom,AnchorPath->ap_Current->an_Info.fib_FileName);
PrintFault(IoErr(),NULL);
}
CurrentDir(ancien_rep);
if (!rv_lr)
{
break;
}
}
}
else
{
/* Traitement d'un fichier */
Un_Fichier *f_tmp;
f_tmp = AllocPooled(contexte->mpool,sizeof(Un_Fichier));
if (f_tmp)
{
ancien_rep = CurrentDir(rep_courant);
if (ajoute_fichier(contexte,AnchorPath->ap_Info.fib_FileName,f_tmp))
{
f_tmp->repertoire = DupLock(AnchorPath->ap_Current->an_Lock);
}
else
{
FreePooled(contexte->mpool,f_tmp,sizeof(Un_Fichier));
}
CurrentDir(ancien_rep);
}
else
{
PrintFault(ERROR_NO_FREE_STORE,mon_nom);
break;
}
}
} /* for (RetVal ...) */
MatchEnd(AnchorPath);
if (RetVal != ERROR_NO_MORE_ENTRIES)
{
Printf("%s : %s - ",mon_nom,*les_fichiers);
PrintFault(RetVal,NULL);
/* Lorsqu'un fichier ou un répertoire n'existe pas
* on passe au suivant. Dans les autres cas on sort */
if ((RetVal != ERROR_OBJECT_NOT_FOUND) &&
(RetVal != ERROR_DEVICE_NOT_MOUNTED))
{
break;
}
}
les_fichiers++;
for (node = contexte->ma_liste.mlh_Head ; node->mln_Succ ; node = node->mln_Succ)
{
Un_Fichier *f_tmp;
f_tmp = (Un_Fichier *)node;
traiter_fichier(contexte,f_tmp);
}
} /* while (*les_fichiers) */
if (contexte->stat)
{
Printf("\n%s statistics :\n",contexte->nom_prog);
Printf("\t%ld Directory(ies) entered\n",contexte->nb_dir_lues);
Printf("\t%ld File(s) processed\n",contexte->nb_fic_lus);
Printf("\t%ld AFM File(s) found\n",contexte->nb_AFM);
Printf("\t%ld PFA File(s) found\n",contexte->nb_PFA);
Printf("\t%ld PFB File(s) found\n",contexte->nb_PFB);
Printf("\t%ld File(s) renamed\n\n",contexte->nb_fic_mv);
}
DeletePool(contexte->mpool);
}
else
{
Printf("%s : Can't Create memory pool - ",mon_nom);
PrintFault(ERROR_NO_FREE_STORE,NULL);
}
FreeVec(contexte);
}
else
{
PrintFault(ERROR_NO_FREE_STORE,mon_nom);
}
FreeDosObject(DOS_FIB,info);
} /* FileInfoBlock */
else
{
Printf("%s : FileInfoBlock's Allocation - ",mon_nom);
PrintFault(ERROR_NO_FREE_STORE,NULL);
}
FreeVec((APTR)AnchorPath);
} /* AnchorPath */
else
{
Printf("%s : AnchorPath's Allocation - ",mon_nom);
PrintFault(ERROR_NO_FREE_STORE,NULL);
}
FreeArgs(RDArgs);
}
else
{
PrintFault(IoErr(),mon_nom);
}
} /* --- main() --- */
/* ------------------------------ traiter_fichier ------------------------------
Commentaire: Traitement d'un fichier. Récupération du nom et renommage si nécessaire
*/
void traiter_fichier(MvPSF_Glo *contexte,Un_Fichier *fic)
{
BPTR fh;
BPTR ancien_rep;
ancien_rep = CurrentDir(fic->repertoire);
fh = Open(fic->nom,MODE_OLDFILE);
if (fh)
{
char chaine[256];
Seek(fh,fic->PosDebut,OFFSET_BEGINNING);
do /* Recherche du nom de la fonte dans le fichier */
{
if (recup_mot(contexte,fh,chaine,sizeof(chaine)))
{
if (!strcmp(chaine,fic->fontname))
{
if (recup_mot(contexte,fh,chaine,sizeof(chaine)))
{
char tmp_nom[108];
int lchaine = strlen(chaine)-1;
/* On filtre le dernier caractère si c'est ) */
if (chaine[lchaine] == ')')
{
chaine[lchaine] = '\0';
}
/* On filtre le premier caractère si c'est ( ou / */
if ((*chaine == '/') || (*chaine == '('))
{
strcpy(tmp_nom,chaine+1);
}
else
{
strcpy(tmp_nom,chaine);
}
strcat(tmp_nom,fic->type);
if (strncmp(fic->nom,tmp_nom,LONGUEUR_NOM - 1))
{
if (Rename(fic->nom,tmp_nom))
{
contexte->nb_fic_mv++;
Printf("Renaming \033[33m%s\033[m to \033[33m%s\033[m\n",fic->nom,tmp_nom);
}
else
{
Printf("%s : %s - ",contexte->nom_prog,fic->nom);
PrintFault(IoErr(),NULL);
}
}
else
{
Printf("%s \033[1mOK\033[m\n",fic->nom);
}
break;
}
else
{
Printf("%s : %s - ",contexte->nom_prog,fic->nom);
PrintFault(IoErr(),NULL);
break;
}
}
else
{
if (!strcmp(chaine,fic->finhead))
{
Printf("Can't find \033[1m%s\033[m in \033[33m%s\033[m\n",fic->fontname,fic->nom);
break;
}
}
}
else
{
LONG erreur = IoErr();
if (erreur)
{
Printf("%s : %s - ",contexte->nom_prog,fic->nom);
PrintFault(IoErr(),NULL);
}
else
{
Printf("Can't find %s in %s\n",fic->fontname,fic->nom);
}
break;
}
} while(1);
Close(fh);
}
else
{
Printf("%s : %s - ",contexte->nom_prog,fic->nom);
PrintFault(IoErr(),NULL);
}
CurrentDir(ancien_rep); /* On revient au répertoire initial */
UnLock(fic->repertoire);/* On libère le "Lock" au répertoire du fichier */
} /* --- traiter_fichier() --- */
/* --------------------------------- recup_mot ---------------------------------
Commentaire: Récupère le mot suivant du fichier fh.
fh : fichier.
chaine : buffer dans lequel sera mis le mot.
longueur : longueur de 'chaine'.
*/
BOOL recup_mot(MvPSF_Glo *contexte,BPTR fh,char *chaine,int longueur)
{
BOOL rv;
int courant = 0;
longueur--;
do
{
LONG buffer = FGetC(fh);
if (buffer < 0)
{
rv = FALSE;
break;
}
if (isspace(buffer))
{
chaine[courant] = '\0';
rv = TRUE;
break;
}
else
{
chaine[courant] = buffer;
courant++;
if (courant >= longueur)
{
chaine[longueur] = '\0';
Printf("Error while parsing line to long\n\t-> (%s)\n",chaine);
rv = FALSE;
break;
}
}
} while(1);
return rv;
} /* -- recup_mot() --- */
/* --------------------------------- lecture_repertoire ---------------------------------
Commentaire: Ajoute les fichiers du répertoire à la liste.
*/
BOOL lecture_repertoire(MvPSF_Glo *contexte,struct FileInfoBlock *info,BPTR rep)
{
BOOL rv;
Un_Fichier *f_tmp = AllocPooled(contexte->mpool,sizeof(Un_Fichier));
if (f_tmp)
{
do
{
if (!ExNext(rep,info))
{
long erreur;
erreur = IoErr();
if (erreur != ERROR_NO_MORE_ENTRIES)
{
Printf("%s : While examining directory - ",contexte->nom_prog);
PrintFault(erreur,NULL);
}
break;
}
if (info->fib_DirEntryType < 0)
{
if (ajoute_fichier(contexte,info->fib_FileName,f_tmp))
{
/* On ajoute le répertoire au fichier qui viens d'être ajouté */
f_tmp->repertoire = DupLock(rep);
f_tmp = AllocPooled(contexte->mpool, sizeof(Un_Fichier));
if (!f_tmp)
{
PrintFault(ERROR_NO_FREE_STORE,contexte->nom_prog);
break;
}
}
}
else if (contexte->verbose)
{
Printf("\t\033[1m%s\033[m is a directory\n",info->fib_FileName);
}
} while(1);
}
else
{
PrintFault(ERROR_NO_FREE_STORE,contexte->nom_prog);
}
if (f_tmp)
{
FreePooled(contexte->mpool,f_tmp,sizeof(Un_Fichier));
rv = TRUE;
}
else
{
rv = FALSE;
}
return rv;
} /* --- lecture_repertoire --- */
/* --------------------------------- ajoute_fichier ---------------------------------
Commentaire: Renvoie TRUE si le fichier et d'un type connu et rempli la structure
fournie. Renvoie FALSE sinon.
Ajoute le fichier à la liste.
*/
BOOL ajoute_fichier(MvPSF_Glo *contexte,char *nom,Un_Fichier *fic)
{
BOOL rv = TRUE;
BPTR fichier;
if (contexte->verbose)
{
Printf("\tProcessing \033[1m%s\033[m\n",nom);
}
fichier = Open(nom,MODE_OLDFILE);
if (fichier)
{
contexte->nb_fic_lus++;
switch (type_fichier(contexte,fichier))
{
case (TYF_AFM) :
{
fic->PosDebut = PosAFM;
strcpy(fic->fontname,AFMFNStr);
strcpy(fic->type,".AFM");
strcpy(fic->finhead,AFMFHStr);
if (contexte->verbose)
{
Printf("\t\t\033[1m%s\033[m is a AFM file\n",nom);
}
contexte->nb_AFM++;
break;
}
case (TYF_PFA) :
{
fic->PosDebut = PosPFA;
strcpy(fic->fontname,PFAFNStr);
strcpy(fic->type,".PFA");
strcpy(fic->finhead,PFAFHStr);
if (contexte->verbose)
{
Printf("\t\t\033[1m%s\033[m is a PFA file\n",nom);
}
contexte->nb_PFA++;
break;
}
case (TYF_PFB) :
{
fic->PosDebut = PosPFB;
strcpy(fic->fontname,PFBFNStr);
strcpy(fic->type,".PFB");
strcpy(fic->finhead,PFBFHStr);
if (contexte->verbose)
{
Printf("\t\t\033[1m%s\033[m is a PFB file\n",nom);
}
contexte->nb_PFB++;
break;
}
case (TYF_NON) :
{
if (contexte->verbose)
{
Printf("\t\t\033[1m%s\033[m doesn't seem to belong to any known type\n",nom);
}
rv = FALSE;
break;
}
case (TYF_ERR) :
{
LONG code_erreur = IoErr();
/* Si le code erreur est nul c'est probablement que le fichier est de longueur nulle */
if (code_erreur)
{
Printf("%s : Error reading file %s - ",contexte->nom_prog,nom);
PrintFault(IoErr(),NULL);
}
else if (contexte->verbose)
{
Printf("\t\t\033[1m%s\033[m doesn't seem to belong to any known type\n",nom);
}
rv = FALSE;
break;
}
}
if (rv)
{
strcpy(fic->nom,nom);
AddTail((struct List *)&contexte->ma_liste,(struct Node *)fic);
}
Close(fichier);
}
else
{
Printf("%s : Error can't open file %s - ",contexte->nom_prog,nom);
PrintFault(IoErr(),NULL);
rv = FALSE;
}
return rv;
} /* --- ajoute_fichier --- */
/* --------------------------------- type_fichier ---------------------------------
Commentaire: Détermine le type du fichier.
*/
TYPE_FICHIER type_fichier(MvPSF_Glo *contexte,BPTR fichier)
{
char buffer[LONG_BUFFER];
TYPE_FICHIER ret_val;
if (Read(fichier,buffer,sizeof(buffer)) > 0)
{
if (!memcmp(buffer,AFMHeader,AFMHeadlong))
{
ret_val = TYF_AFM;
}
else if (!memcmp(buffer,PFBHeader,PFBHeadlong) &&
(!memcmp(buffer+PosPFB,PFA1Header,PFA1Headlong) ||
!memcmp(buffer+PosPFB,PFA2Header,PFA2Headlong)))
{
ret_val = TYF_PFB;
}
else if (!memcmp(buffer,PFA1Header,PFA1Headlong) ||
!memcmp(buffer,PFA2Header,PFA2Headlong))
{
ret_val = TYF_PFA;
}
else
{
ret_val = TYF_NON;
}
}
else
{
ret_val = TYF_ERR;
}
return ret_val;
} /* --- type_fichier --- */
/* ---
* $Log: MvPSF.c,v $
* Revision 1.4 1996/04/10 21:30:16 Christophe_Labouisse
* Correction RCS Version -> Revision
*
* Revision 1.3 1996/04/10 21:25:37 Christophe_Labouisse
* Ajout des statistiques.
* Utilisation de RCS pour le numéro de version.
*
* Revision 1.2 1996/04/07 14:47:27 LABOUISSE_Christophe
* Ajout des mots clés VERBOSE et ALL
* Nouvelle utilisation des arguments permettant maintenant d'avoir plusieurs
* fichiers ou répertoires traités en une seule commande.
*
* Revision 1.1 1996/03/23 22:46:43 LABOUISSE_Christophe
* Initial revision
*
} /* --- */